home *** CD-ROM | disk | FTP | other *** search
- Path: news.acadia.net!usenet
- From: steven2@salesbook.com (Steve Nutt)
- Newsgroups: comp.lang.c++
- Subject: Re: C++ OO question (long)
- Date: Sun, 03 Mar 1996 06:35:38 GMT
- Organization: DET
- Message-ID: <4hb5tb$91l@post.acadia.net>
- References: <4h08uq$mve@madeline.INS.CWRU.Edu>
- Reply-To: steven2@salesbook.com
- NNTP-Posting-Host: blf7.acadia.net
- X-Newsreader: Forte Free Agent 1.0.82
-
- bf461@cleveland.Freenet.Edu (Bryan Murphy) wrote:
-
-
-
- >/*
- >Warning: This is a long one.
-
- >Ok, I'm fairly new to the C++ programming paradigm. While I've
- >quite a bit of experience with the C++ syntax, I've only just
- >begun to understand the concepts that really go into an OOP
- >program.
-
- >Anyways, I have to write a program for a class, all it needs to
- >do is multiply two matrices together, but I decided to brush up
- >on my C++ and to forgoe using ada or pascal to just throw some-
- >thing together.
-
- >Bellow is the program I wrote. It implements a class called
- >Matrix, which allocates memory on the heap for the storage of
- >a matrix of XxY dimensions. It also implements a copy constructor
- >for assignment, and a couple of different mathematical operations
- >to be performed on the matrix.
-
- >I've got one big problem, and one little one, even though this
- >does compile and run fine the way it is (I'm compiling this as
- >a Visual C++ 4.0 Console Application).
-
- >The first problem involves this very peculiar inconsistency that
- >I can't explain, for instance, this works:
-
- > Matrix M3 = Matrix1 * Matrix2;
-
- >whereas defining Matrix M3 ahead of time
-
- > M3 = Matrix1 * Matrix2;
-
- >crashes out on me giving me an error. I can't really tell why.
- >It's a memory allocation assertion error. I can't figure out
- >why I can't do the second method. I was thinking about this,
- >and I have another question related to this. When I define
- >the Matrix M3 and assign it right away, is the Default Blank
- >Constructor called, THEN the Copy Constructor? Or just the
- >copy constructor? Also, say the copy Constructor was called.
- >When the new data is copied over, is the Destructor called
- >before the copy constructor is used to copy the new data over?
- >I think these questions could definately shed some light as to
- >the inconsistency noted above.
-
- Well I looked into this just yesterday and I found the following.
-
- Matric M3 = Matrix1 * Matrix2;
-
- is (just about) identical to
-
- Matrix M3 (Matrix1 * Matrix2);
-
- The only possiable difference is that there might be an extra temp
- variable created in the first case but most good compilers shouldn't.
-
- >Also, my second problem is pretty simple. It relates to using
- >variable arguments. Is there anything peculiar or different
- >about Visual C++'s variable arguments? I was trying to initialize
- >the Matrices by using variable arguments, rather than passing
- >a pointer to an array of Integers, but I could not get the
- >constructor to get the proper numbers. I was basing the code
- >EXACTLY like what was in my C++ for Pascal Programmers book,
- >nearly statement by statement, but it didn't work. Visual C++
- >accepted the syntax, and everything looked ok, but I was just
- >not getting the right values.
-
- >Here is the CPP file. It's one file and can be copied. I even
- >commented out this text so you can just save the message to
- >a file and copy it directly if you would like to take a look at
- >it.
-
- >Any help would be GREATLY appreciated!
- >*/
-
- >/******************************************************************
- >
- > Author: Bryan Murphy
- > Class: CPS 341
- > Teacher: Y. Pan
- > Due Date: Monday 3/4/96
-
- > This program implements a Matrix class and the appropriate
- > Multiplication and Division functions for that class. The
- > program then demonstrates the use of this class.
-
- >******************************************************************/
- >#include "iostream.h"
- >#include "stdarg.h"
- >#include "stdlib.h"
-
- >class Matrix {
- >public:
- > Matrix(); // Constructor
- > Matrix(int,int,int const *); // Constructor
- > ~Matrix(); // Destructor
-
- > Matrix(const Matrix &); // Copy Constructor
-
- > int GetData(int,int); // Get Number from Matrix
- > void SetData(int,int,int); // Set a Value in the Matrix
- > void Display(void); // Display Contents of Matrix
-
- > int Xdim() { return xdim+1; } // In case the size needs
- > int Ydim() { return ydim+1; } // to be checked.
-
- Missing operator = This will be a big problem if the compiler is
- generating one for you!
- Matrix& operator = (const Matrix& rhs)
- {
- ~Matrix(); // Big hack, but I'm not going to write your code :-)
- Matrix (rhs); // Should work, just isn't nice
- return *this;
- }
-
- > // The following are the operations that can be
- > // performed on a matrix.
- > friend Matrix operator * (Matrix, Matrix); // Matrix *
- > friend Matrix operator * (Matrix, int); // Scalar *
- > friend Matrix operator + (Matrix, Matrix); // Matrix +
- > friend Matrix operator - (Matrix, Matrix); // Matrix -
- >
- >private:
-
- > int xdim; // X size of Matrix
- > int ydim; // Y size of Matrix
-
- > int *MatrixData; // Contents of Matrix
- >};
-
-
- >// Matrix Constructor. This constructor initializes the
- >// matrix and allocates memory for the matrix data.
- >Matrix::Matrix(int x, int y, int const *data = 0)
- >{
- > // Set matrix size (numbering system 0 to X-1)
- > xdim = (x-1);
- > ydim = (y-1);
-
- > // Allocate memory for matrix
- > MatrixData = new int[x*y];
-
- > // Check for memory allocation error
- > if (MatrixData == 0) throw "Memory Allocation Error";
-
- > // Copy Data to Matrix if Available
- > if (data !=0)
- > for (int i=0; i<x*y; i++) MatrixData[i] = data[i];
- > else
- > for (int i=0; i<x*y; i++) MatrixData[i] = 0;
-
- >}
-
- >// This constructor is for special cases where we don't
- >// know what the resulting member will look like.
- >Matrix::Matrix()
- >{
- > xdim = 0;
- > ydim = 0;
- > MatrixData = 0;
- >}
-
- >// Matrix Destructor. Clean up the mess.
- >Matrix::~Matrix()
- >{
- > // Free up the memory used
- > delete MatrixData;
- >}
-
- >// This is used for copying and assignment (ie. Matrx = Matrx2;)
- >Matrix::Matrix(const Matrix &Mat)
- >{
- > int size = (Mat.xdim+1)*(Mat.ydim+1);
- > MatrixData = new int[size];
-
- > xdim = Mat.xdim;
- > ydim = Mat.ydim;
-
- > // Copy the Data over
- > for (int i=0; i<size; i++) MatrixData[i] = Mat.MatrixData[i];
- >
- >}
-
- >// This function is used to get a specific value from a
- >// matrix in position (x,y)
- >int Matrix::GetData(int x,int y)
- >{
- > // Convert to matrix indices
- > x--;
- > y--;
-
- > // Make sure X and Y are within bounds
- > if (x<0 || x>xdim) throw("X out of Matrix Bounds");
- > if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
- >
- > // Return Value if no Exceptions Raised
- > return MatrixData[y+x*(ydim+1)];
- >}
-
- >// Set a value in a Matrix
- >void Matrix::SetData(int x,int y,int value)
- >{
- > // Convert to matrix indices
- > x--;
- > y--;
-
- > // Make sure X and Y are within bounds
- > if (x<0 || x>xdim) throw("X out of Matrix Bounds");
- > if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
-
- > MatrixData[y+x*(ydim+1)] = value;
- >}
-
- >// Display the Contents of the Matrix
- >void Matrix::Display(void)
- >{
- > // Just in Case...
- > if (MatrixData == 0) throw("Internal Matrix Error!");
-
- > cout << xdim+1 << "x" << ydim+1 << " Matrix" << endl;
-
- > // Display Matrix
- > for (int x=0; x<=xdim; x++)
- > {
- > for (int y=0; y<=ydim; y++)
- > {
- > // For Formatting Purposes
- > if (MatrixData[y+x*(ydim+1)] < 10)
- > cout << " ";
-
- > cout << " " << MatrixData[y+x*(ydim+1)];
- > }
- > cout << endl;
- > }
- >}
-
-
- >// * operator for Matrices
- >Matrix operator * (Matrix M1, Matrix M2)
- >{
- > // M1 columns must equal M2 rows
- > if (M1.ydim != M2.xdim)
- > throw "Matrices cannnot be multiplied!";
-
- > Matrix M3(M1.xdim+1,M2.ydim+1);
-
- > // Do the Multiplication
- > for (int i=1; i<M1.Xdim(); i++)
- > for (int j=1; j<M2.Ydim(); j++)
- > {
- > M3.SetData(i,j,0);
- > for (int k=1; k<M2.Xdim(); k++)
- > M3.SetData(i,j,M3.GetData(i,j)+
- > M1.GetData(i,k)*M2.GetData(k,j));
- > }
-
- > return M3;
- >}
-
- >// This is for multiplication by a Scalar
- >Matrix operator * (Matrix M1, int Scalar)
- >{
- > Matrix Temp(M1.xdim+1,M1.ydim+1);
- > int size = (M1.xdim+1)*(M1.ydim+1);
-
- > // Multiply matrix by scalar
- > for (int i=0; i<size; i++)
- > Temp.MatrixData[i] = M1.MatrixData[i] * Scalar;
-
- > return Temp;
- >}
-
- >// Add two Matrices together
- >Matrix operator + (Matrix M1, Matrix M2)
- >{
- > // Matrices must be same dimensions
- > if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
- > throw "Matrices cannot be added!";
-
- > Matrix Temp(M1.xdim+1,M1.ydim+1);
- > int size = (M1.xdim+1)*(M1.ydim+1);
-
- > // Do the addition
- > for (int i=0; i<size; i++)
- > Temp.MatrixData[i] = M1.MatrixData[i] + M2.MatrixData[i];
-
- > return Temp;
- >}
-
- >// Subtract two Matrices
- >Matrix operator - (Matrix M1, Matrix M2)
- >{
- > // Matrices must be same dimensions
- > if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
- > throw "Matrices cannot be subtracted!";
-
- > Matrix Temp(M1.xdim+1,M1.ydim+1);
- > int size = (M1.xdim+1)*(M1.ydim+1);
-
- > // Do the Subtraction
- > for (int i=0; i<size; i++)
- > Temp.MatrixData[i] = M1.MatrixData[i] - M2.MatrixData[i];
-
- > return Temp;
- >}
-
- >// Define matrix data as arrays
- >int Mat4x4a[16] = {1, 2, 3, 4,
- > 5, 6, 7, 8,
- > 9, 10,11,12,
- > 13,14,15,16};
-
- >int Mat4x4b[16] = {0, 1, 1, 1,
- > 1, 0, 1, 1,
- > 1, 1, 0, 1,
- > 1, 1, 1, 0};
-
- >main()
- >{
- > // Define Two Matrix Variables
- > Matrix M1(4,4, Mat4x4a);
- > Matrix M2(4,4, Mat4x4b);
-
- > // Test Matrix Operations
- > Matrix M3 = M1 * M2;
- > Matrix M4 = M2 * M1;
- > Matrix M5 = M1 + M2;
-
- > // Print out the Results
- > cout << "Matrix A:" << endl; M1.Display();
- > cout << "Matrix B:" << endl; M2.Display();
- > cout << "Matrix A*B:" << endl; M3.Display();
- > cout << "Matrix B*A:" << endl; M4.Display();
- > cout << "Matrix A+B:" << endl; M5.Display();
-
- > return 0;
- >}
- >--
-
-
-